package com.liuym.common.redis;

import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;

import java.time.Duration;
import java.util.HashSet;
import java.util.Set;

public class RedisConfigCommon {
    public LettuceConnectionFactory lettuceConnectionFactory(String hostName, int port, String password, int database) {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        // redis节点--the hostname or ip of the Redis node
        config.setHostName(hostName);
        // redis 端口
        config.setPort(port);
        // 登陆密码，不能为空
        config.setPassword(RedisPassword.of(password));
        config.setDatabase(database);
        // lettuce 线程池---a single thread-safe native connection by default；主要特点就是安全
        return new LettuceConnectionFactory(config);
    }

    public LettuceConnectionFactory lettuceConnectionFactory(String url, String password, int database) {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        String[] split = url.split(":");
        // redis节点--the hostname or ip of the Redis node
        config.setHostName(split[0]);
        // redis 端口
        config.setPort(Integer.valueOf(split[1]));
        // 登陆密码，不能为空
        config.setPassword(RedisPassword.of(password));
        config.setDatabase(database);
        // lettuce 线程池---a single thread-safe native connection by default；主要特点就是安全
        return new LettuceConnectionFactory(config);
    }

    //缓存管理器
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, int ttl, String cacheName) {
        //Redis配置类
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) //序列化
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new JdkSerializationRedisSerializer()))
                .entryTtl(Duration.ofSeconds(ttl)) //失效时间
                //.prefixKeysWith("agent:") //前缀
                .disableCachingNullValues();

        //创建CacheManager对象
        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory);

        builder.cacheDefaults(config);
        builder.transactionAware();
        if (cacheName != null) {
            Set<String> cacheNames = new HashSet<String>();
            cacheNames.add(cacheName);
            builder.initialCacheNames(cacheNames);
        }
        return builder.build();
    }

    public RedisTemplate<String, String> getRedisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, String> template = new RedisTemplate<>();
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringSerializer);
        template.setValueSerializer(stringSerializer);
        template.setHashKeySerializer(stringSerializer);
        template.setHashValueSerializer(stringSerializer);
        template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
        template.setEnableDefaultSerializer(true);
        template.setConnectionFactory(connectionFactory);
        return template;
    }
}
